home *** CD-ROM | disk | FTP | other *** search
/ Amiga Plus 1995 #5 & #6 / Amiga Plus CD - 1995 - No. 5 and 6.iso / pd / serien / purity / nr.12 / workshop / pascalkursi.txt < prev    next >
Text File  |  1995-04-21  |  18KB  |  421 lines

  1.  
  2.   +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  3.   +                 Systemprogrammierung in PCQ-Pascal                  +
  4.   +               Kurs für AMIGAGadget und Purity- Teil I               +
  5.   +++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
  6.  
  7. Viele kennen Turbo Pascal vom PC. Mit dem PCQ-Compiler von der Fish-Disk
  8. 503 steht nun auf dem Amiga ein billiger und leistungsfähiger Pascal-
  9. Compiler zur Verfügung. Nun ist der grundsätzliche Iso-Standard
  10. implementiert, die Systemprogrammierung stellt aber PC-Programmierer
  11. vor ein Rätsel. Deshalb nun - ein Kurs ! (Tusch...)
  12. Der kann natürlich auch mit der PCQ Version 1.1 durchgeführt werden, aber
  13. hauptsächlich wegen der Includefiles empfiehlt sich Version 1.2.
  14.  
  15. I. Voraussetzungen
  16.  
  17. Um diesem Kurs folgen zu können, sollte man sich mit dem CLI auskennen.
  18. Außerdem brauchte man den PCQ-Compiler inklusive dem Assembler A68k
  19. und dem BLink. Mit diesen sollte man sich auch auskennen (notfalls im
  20. DOC-File von PCQ nachlesen). Als erstes stelle man sich eine bootfähige
  21. Pascaldisk zusammen. Der Pcq kommt als "Pascal" in den C-Ordner, wohin
  22. ihm der A68k und BLink folgen. Die PCQ.Lib kommt einfach in das
  23. Rootdirectory (man könnte auch ein eigenes Libraries-Subdirectory
  24. erstellen, aber bei einer Library lohnt sich das kaum...). Desweiteren
  25. benötigen wir noch den Include-Ordner und einen ASCII-Editor (es
  26. empfiehlt sich der DME). Das war's schon an Voraussetzungen.
  27. Nun kann's losgehen.
  28.  
  29. II. Screens und Windows
  30.  
  31. Wie aus der Überschrift erkennbar, soll es unsere erste Aufgabe sein,
  32. erstmal einen eigenen Bildschirm zu öffnen. Nun gibt es auf dem Amiga
  33. verschiedene Programme, die sich um bestimmte Aufgabenteile kümmern,
  34. die sogenannten "Libraries". Bevor man sich an ihren Routinen gütlich
  35. tun kann, muß man sie erstmal öffnen. Nun brauchen wir, um einen
  36. Screen zu öffnen, natürlich nicht alle Libraries, sondern nur die
  37. sogenannten "Intuition.Library". Sie kümmert sich um Fenster,
  38. Bildschirme, Menüleisten und Gadgets (da gibt's kein deutsches Wort,
  39. das passt...oder ?). Und - wie schön für uns - da der Startupcode
  40. von PCQ-Pascal diese Library schon benötigt, brauchen wir sie noch
  41. nicht einmal mehr von Hand aufzumachen. Auf alle von ihr zur Verfügung
  42. gestellten Routinen können wir in einem PCQ-Programm ohne Umstände
  43. zurückgreifen. (Na ja, das wird später noch eingeschränkt....
  44. wartet's ab.) Ein's muß man aber doch tun : das File "Intuition.I"
  45. in den Programmcode einbinden. Das geht ganz einfach : mit dem
  46. Compilerbefehl ($I "Include:Intuition/Intuition.I" }. Er öffnet ein File,
  47. in dem diverse Strukturen zur Verwaltung von Strukturen des Systems
  48. enthalten sind.
  49. Unser Programm sieht also so aus :
  50.  
  51.         Program IntuitionTest (input , output);
  52.  
  53.         { Listing für den AMIGAGadget/Purity - Pascalkurs , Grundgerüst }
  54.  
  55.         {$I "Include:Intuition/Intuition.I" }
  56.  
  57.         BEGIN
  58.         END.
  59.  
  60. Was macht das Programm ? Antwort : nichts, da der Programmblock leer
  61. ist. Allerdings ist es ein Gerüst, in das man beliebige Intuition-
  62. operationen einbauen kann. Um einen Bildschirm zu öffnen, muß man die
  63. Funktion "OpenScreen" aufrufen. Sie benötigt als Parameter die Addresse
  64. einer NewScreen-Struktur, in der die Daten für den zu erstellenden
  65. Bildschirm enthalten sind. Der Wert, den sie zurückliefert ist
  66. entweder Null (=NIL), wenn der Versuch, den Bildschirm zu öffnen,
  67. fehlgeschlagen ist (passiert bei uns nicht !!! Oder MEISTENS nicht...)
  68. oder ein Zeiger auf eine Screenstruktur, die die Daten des geöffneten
  69. Bildschirms enthält.
  70. Wie sieht nun diese NewScreen-Struktur aus ? Antwort : so :
  71.  
  72.   NewScreen = record
  73.     LeftEdge,               linke Ecke des Screens (meistens 0)
  74.     TopEdge,                obere Ecke des Screens (meistens 0)
  75.     Width,                  Breite des Screens (mstns. 320 o. 640)
  76.     Height,                 Höhe des Screens (mstns. 256 o. 512)
  77.     Depth   : Short;        Anzahl der Bitplanes (siehe A 1)
  78.     DetailPen,              Registernummer des Zeichenstifts (A 2)
  79.     BlockPen : Byte;        Registernummer des Blockstifts (A 2)
  80.     ViewModes : Short;      legt den sogenannten ViewPort fest (A 3)
  81.     SType     : Short;      Art des Screens (A 4)
  82.     Font      : Address;    Zeiger auf den Schriftsatz (mstns. Nil)
  83.     DefaultTitle : String;  Zeiger auf den Titel des Screens
  84.     Gadgets      : Address; Zeiger auf Screengadgets (unwichtig)
  85.     CustomBitMap : Address; Zeiger auf selbstgemachte BitMap (mstns. Nil)
  86.   end;
  87.  
  88.   A 1 : Um die Anzahl der Farben zu bestimmen, muß man sogenannte
  89.         Bitplanes verwenden. Diese kann man sich in etwa als große
  90.         rechteckige "Bitflächen" vorstellen.
  91.  
  92.         +-------------------+   Um dies zu verstehen, muß man sich
  93.         |                   |   mit der Art und Weise befassen, in der
  94.         |                   |   der Amiga seine Grafik darstellt.
  95.         |                   |   Dies funktioniert, indem jedem Punkt
  96.         |                   |   des Bildschirms ein Bit pro
  97.         +-------------------+   Bitplane zugeordnet ist.
  98.  
  99.         Ein Bildpunkt kann nun pro Bitplane also zwei Zustände
  100.         annehmen : Bit gesetzt und Bit nicht gesetzt.
  101.         Bei einer Bitplane kann es also nur zwei Arten von
  102.         Bildpunkten geben : 0 (Bit in Bitplane nicht gesetzt)
  103.         und 1. Was sollen nun diese Zahlen ?? Was bestimmen sie ?
  104.         Ganz einfach : pro Bildschirm stellt der Amiga eine
  105.         bestimmte Anzahl von Farben zur Verfügung (nämlich exakt
  106.         zwei hoch Anzahl der Bitplanes, in unserem Falle 2 hoch 1=2).
  107.         Diese sind von 0 bis (2^Anzahl)-1 durchnummeriert, bei uns
  108.         also 0 und 1. Aha !!! Die Bits der Bitplane zeigen also auf
  109.         das Farbregister, mit dem der entsprechende Bildpunkt
  110.         eingefärbt wird. Nun legen wir auf diese eine Bitplane noch
  111.         eine zweite drauf. Betrachtet wir einen Ausschnitt :
  112.  
  113.         1.Bitplane :  001001110010
  114.         2.Bitplane :  010000110101
  115.  
  116.         Man sieht, es gibt vier Kombinationsmöglichkeiten :
  117.         (die erste Zahl ist die höchste Bitplane)
  118.         00 , 01 , 10 , 11 - Binärzahlen. Ich gehe mal davon aus, daß
  119.         jeder mit ihnen umgehen kann. Dezimal geschrieben gibt es also
  120.         folgende Zuweisungsmöglichkeiten bei 2 Bitplanes :
  121.         0 , 1 , 2 , 3. Man ahnt schon, was diese Zahlen bedeuten :
  122.         sie kennzeichnen das Register (den Farbtopf), aus dem der
  123.         Amiga die Farbe zur Darstellung des entsprechenden Bildpunktes
  124.         schöpfen muß. Und zuguterletzt noch die Variante mit
  125.         3 Bitplanes :
  126.  
  127.         1.BP : 001001110010
  128.         2.BP : 010000110101
  129.         3.BP : 010101101010
  130.  
  131.         Und schupdiwupp, da sind es acht Kombinationsmöglichkeiten :
  132.  
  133.         000 , 001 , 010 , 011 , 100 , 101 , 110 , 111 - dezimal 0-7.
  134.         Und so weiter...
  135.  
  136.         Quintessenz : Will man einen Screen mit 16 Farben, dann nehme
  137.         man für Depth den Wert 4 (2^4 = 16). Für 32 muß man 5 Bitplanes
  138.         wählen.
  139.  
  140.   A 2 : Diese Zahlen beziehen sich auf das in A 1 angesprochene
  141.         Farbregister (0 - (2^Anzahl Bitplanes)-1).
  142.  
  143.   A 3 : Ein Screen ist ein Element, das relativ weit entfernt vom System
  144.         ist. Weiter unten ist die sogenannte View-Struktur zu finden.
  145.         "Auf ihr drauf" liegen ViewPorts, die man besser modifizieren
  146.         kann als Views. "Auf denen" findet man nun RastPorts, welche
  147.         wieder Teile von Screens sind, die wiederrum "unter" Windows
  148.         liegen, welche den Inbegriff der Manipulationsfreundlichkeit
  149.         darstellen. Nun sehen Standardviewports für Screens eine
  150.         maximale horizontale Auflösung von 320 Pixeln und eine
  151.         vertikale von 256 Pixeln vor. Um dies zu ändern, muß man
  152.         das Feld ViewModes mit diversen Werten belegen. Diese sind
  153.         in "Include:Graphics/View.I" (wird von Intuition.I mit einge-
  154.         lesen) vordefiniert. So gibt es z.B. HIRES (erlaubt 640 Pixel
  155.         horizontal) und LACE (aktiviert den sogenannten Interlace-Modus,
  156.         welcher über einen Trick 512 vertikale Pixel erlaubt).
  157.  
  158.   A 4 : Es gibt zwei Arten von Screen : den CUSTOMSCREEN_f (wird in
  159.         "include:Intuition/Intuition.i" definiert). Er ist sehr praktisch
  160.         und wird auch meistens verwendet. Nachteil : sollten Sys-Requester
  161.         (kennt jeder : "Disk is NOT a DOS Disk" , "Read/Write error",
  162.         "No Disk present in", etc..) geöffnet werden, so wird der
  163.         Workbenchscreen in den Vordergrund geschaltet, was
  164.         verständlicherweise nicht besonders professionell wirkt.
  165.         Die Alternative ist WBENCHSCREEN_f. Hier werden System-Requester
  166.         auf dem Screen geöffnet. Traumhaft. Nachteil : man kriegt
  167.         Probleme, wenn man in der Farbstruktur der Preferences
  168.         rumpfuscht und wenn man aus Versehen den "alten" Workbenchscreen
  169.         in den Vordergrund geschaltet hat und das eigene Programm
  170.         öffnet plötzlich ein Fenster, dann erscheint dies auf dem
  171.         "alten" Screen....
  172.  
  173. Also gut, hauen wir einen Screen auf.
  174.  
  175.  
  176.         Program IntuitionTest (input , output);
  177.  
  178.         { Listing für den AMIGAGadget/Purity - Pascalkurs , Screen öffnen }
  179.  
  180.         {$I "Include:Intuition/Intuition.I" }
  181.  
  182.         VAR
  183.                 myscreen : ScreenPtr;
  184.  
  185.  
  186.         PROCEDURE CloseDisplay;
  187.  
  188.         { Sollte ein Teil des Displays offen sein, dann wird er von }
  189.         { dieser Routine geschlossen.                               }
  190.  
  191.         BEGIN
  192.          IF myscreen<>NIL THEN CloseScreen (myscreen);
  193.         END;
  194.  
  195.  
  196.         PROCEDURE BreakProgram (reason : STRING);
  197.  
  198.         { Diese Routine schließt alles bisher geöffnete, druckt den }
  199.         { Fehlergrund aus und bricht dann das Programm ab.          }
  200.  
  201.         BEGIN
  202.          CloseDisplay;
  203.          WRITELN ('Program error : ',reason);
  204.          Exit (42);
  205.         END;
  206.  
  207.         PROCEDURE OpenDisplay;
  208.  
  209.         { Diese Routine erstellt ein Display.                       }
  210.  
  211.         CONST
  212.                 mynewscreen : NewScreen = (0,0,640,256,2,0,1,HIRES,
  213.                                             CUSTOMSCREEN_f,NIL,
  214.                                             "Unser erster Screen",NIL,NIL);
  215.         BEGIN
  216.           myscreen := OpenScreen (Adr(mynewscreen));
  217.           IF myscreen=NIL THEN BreakProgram ("Couldn't open Screen");
  218.         END;
  219.  
  220.         PROCEDURE WarteEinWenig;
  221.  
  222.         { Eine unelegante Routine, die nur dazu dient,das geöffnete }
  223.         { Display zu betrachten. In späteren Programmen, wird sie   }
  224.         { durch eleganteren Stuff ersetzt.                          }
  225.  
  226.         VAR ww1 , ww2 : INTEGER;
  227.  
  228.         BEGIN
  229.           FOR ww1:=1 TO 100 DO
  230.            FOR ww2:=1 TO 2000 DO;
  231.         END;
  232.  
  233.  
  234.         BEGIN
  235.           OpenDisplay;
  236.           WarteEinWenig;
  237.           CloseDisplay;
  238.         END.
  239.  
  240. Alles klar ?? Nun gut, wenden wir uns dem Window zu. Prinzipiell
  241. funktioniert die Sache wie mit dem Screen : NewWindowStruktur
  242. an OpenWindow übergeben, Zeiger auf WindowStruktur zurückerhalten.
  243. Also schnell der Blick auf die NewWindow-Struktur :
  244.  
  245.     NewWindow = record
  246.         LeftEdge,
  247.         TopEdge,
  248.         Width,
  249.         Height          : Short;
  250.         DetailPen,
  251.         BlockPen        : Byte;         siehe NewScreen-Struktur
  252.         IDCMPFlags      : Integer;      siehe B 1
  253.         Flags           : Integer;      siehe B 2
  254.         FirstGadget     : Address;      Zeiger auf das erste Gadget
  255.         CheckMark       : Address;      unwichtig
  256.         Title           : String;       Zeiger auf Titel des Windows
  257.         Screen          : Address;      Zeiger auf den Screen
  258.         BitMap          : Address;      Zeiger auf eigene BitMap
  259.         MinWidth,                       siehe B 2
  260.         MinHeight,
  261.         MaxWidth,
  262.         MaxHeight       : Short;
  263.         WType           : Short;        siehe SType bei NewScreen
  264.     end;
  265.  
  266.   B 1 : Der IDCMP-Port ist die Brücke zwischen dem Benutzer und
  267.         Intuition. Hier wird dem Programmierer mitgeteilt, was der
  268.         Anwender mit Intuition vorhat. Dies beinhaltet so Sachen wie
  269.         Mausknopf gedrückt , Window geschlossen , etc. . Hiermit
  270.         beschäftigen wir uns in der nächsten Folge im Kapitel
  271.         Messages.
  272.  
  273.   B 2 : Hier werden einige grundlegende Eigenschaften des Windows
  274.         festgelegt. Definiert in "Intuition.I" sind folgende :
  275.  
  276.     WINDOWSIZING    : die Größe des Windows kann verändert werden.
  277.                       Maximum sowie Minimum der Windowgröße kann
  278.                       in den Feldern MinWidth,MinHeight,MaxWidth
  279.                       und MaxHeight festgelegt werden.
  280.     WINDOWDRAG      : man kann das Window durch die Gegend ziehen.
  281.     WINDOWDEPTH     : das Window bekommt Gadgets, mit denen man es
  282.                       hinter andere Windows schalten kann.
  283.     WINDOWCLOSE     : das Window erhält in der linken oberen
  284.                       Ecke ein Closegadget. Abfragen muß man es aber
  285.                       selber - wartet auf die nächste Folge.
  286.     SIZEBRIGHT    und
  287.     SIZEBBOTTOM     : treffen unwesentliche Aussagen über den Ort
  288.                       des WindowSizing-Gadgets
  289.     SMART_REFRESH   : der Amiga merkt sich in einem Speicherbereich,
  290.                       den er extra reserviert, Teile des Fensterinhalts,
  291.                       wenn dieses von anderen Fenstern überlagert
  292.                       wird. Normalerweise verwendet man diesen Modus.
  293.     SIMPLE_REFRESH  : Man erhält nur eine Message (nächste Folge !!!),
  294.                       wenn der Fensterinhalt wieder erneurt werden muß
  295.                       (da z.B. ein Filerequester Teile des Fensters
  296.                       überlagert hatte). Um den Vorgang an sich muß man
  297.                       sich aber selbst kümmern...
  298.     SUPER_BITMAP    : sehr speicherintensive Refreshalternative. Ein
  299.                       Speicherbereich im Amiga enthält den gesamten
  300.                       Fensterinhalt. Das dargestellte Window kann auch
  301.                       nur ein Ausschnitt aus dieser "SuperBitmap" sein..
  302.     OTHER_REFRESH   : na ja...
  303.     BACKDROP        : ganz tolles Flag : das Window ist immer hinter
  304.                       allen anderen Windows des Screens
  305.     REPORTMOUSE_f   : Intuition speichert die aktuellen Mauskoordinaten
  306.                       in den Feldern MouseX und MouseY der
  307.                       Windowstruktur.
  308.     GIMMEZEROZERO   : Intuition betrachtet den Inhalt des Fensters
  309.                       getrennt von den äußeren Applikationen (Rahmen,
  310.                       Gadgets, etc.)
  311.     BORDERLESS      : das Fenster bekommt keinen Rahmen
  312.     ACTIVATE        : das Fenster wird nach dem Öffnen gleich aktiviert
  313.     WINDOWACTIVE    : das Fenster ist das gerade aktive
  314.     INREQUEST       : das Fenster ist im Requester-Modus
  315.     MENUSTATE       : die Menuleiste ist heruntergeklappt
  316.     RMBTRAP         : der rechte Mausknopf wird wie der linke behandelt
  317.     + einige absolut unwichtige
  318.  
  319. Genug der grauen Theorie - öffnet das Fenster !!!
  320.  
  321.  
  322.         Program IntuitionTest (input , output);
  323.  
  324.         { Listing für den AMIGAGadget/Purity - Pascalkurs ,            }
  325.         { Screen+Window öffnen                                         }
  326.  
  327.         {$I "Include:Intuition/Intuition.I" }
  328.  
  329.         VAR
  330.                 myscreen : ScreenPtr;
  331.                 mywindow : WindowPtr;
  332.  
  333.  
  334.         PROCEDURE CloseDisplay;
  335.  
  336.         { Sollte ein Teil des Displays offen sein, dann wird er von }
  337.         { dieser Routine geschlossen.                               }
  338.  
  339.         BEGIN
  340.          IF myscreen<>NIL THEN
  341.           CloseScreen (myscreen);
  342.          IF mywindow<>NIL THEN
  343.           CloseWindow (mywindow);
  344.         END;
  345.  
  346.  
  347.         PROCEDURE BreakProgram (reason : STRING);
  348.  
  349.         { Diese Routine schließt alles bisher geöffnete, druckt den }
  350.         { Fehlergrund aus und bricht dann das Programm ab.          }
  351.  
  352.         BEGIN
  353.          CloseDisplay;
  354.          WRITELN ('Program error : ',reason);
  355.          Exit (42);
  356.         END;
  357.  
  358.         PROCEDURE OpenDisplay;
  359.  
  360.         { Diese Routine erstellt ein Display.                       }
  361.  
  362.         CONST
  363.                 mynewscreen : NewScreen = (0,0,640,256,2,0,1,HIRES,
  364.                                             CUSTOMSCREEN_f,NIL,
  365.                                             "Unser zweiter Screen",NIL,NIL);
  366.  
  367.                 mynewwindow : NewWindow = (0,0,400,200,0,1,0,
  368.                                            SMART_REFRESH+ACTIVATE+
  369.                                            WINDOWDRAG,NIL,NIL,"Unser erstes Fenster",
  370.                                            NIL,NIL,0,0,0,0,CUSTOMSCREEN_f);
  371.  
  372.         BEGIN
  373.           myscreen := OpenScreen (Adr(mynewscreen));
  374.           IF myscreen=NIL THEN BreakProgram ("Couldn't open Screen");
  375.           mynewwindow.Screen:=myscreen;
  376.           mywindow := OpenWindow (Adr(mynewwindow));
  377.           IF mywindow=NIL THEN BreakProgram ("Couldn't open Window");
  378.         END;
  379.  
  380.         PROCEDURE WarteEinWenig;
  381.  
  382.         { Eine unelegante Routine, die nur dazu dient,das geöffnete }
  383.         { Display zu betrachten. In späteren Programmen, wird sie   }
  384.         { durch eleganteren Stuff ersetzt.                          }
  385.  
  386.         VAR ww1 , ww2 : INTEGER;
  387.  
  388.         BEGIN
  389.           FOR ww1:=1 TO 500 DO
  390.            FOR ww2:=1 TO 2000 DO;
  391.         END;
  392.  
  393.  
  394.         BEGIN
  395.           OpenDisplay;
  396.           WarteEinWenig;
  397.           CloseDisplay;
  398.         END.
  399.  
  400. So, das war's für heute. Probiert schön fleißig mal mit allen
  401. möglichen Window- und Screentypen herum.
  402. Sollte es Probleme oder Fragen geben, so wendet Euch mit einem
  403. Leserbrief an die Purity oder direkt an mich
  404.  
  405.             Andreas Neumann
  406.             Auf dem Ruhbühl 151
  407.             W 7997 Immenstaad
  408.             Tel.: 07545 / 3483
  409.  
  410. Übrigens : alle Routinen, die wir hier in dem Kurs entwickeln, können
  411. ruhig in eigene Programme übernommen werden. Ein Hinweis auf diesen
  412. tollen Kurs von mir wäre aber ganz nett.
  413. Viel Spaß und bis zur nächsten Purity, in dem es wieder heißt
  414.  
  415.         "END. gut , alles gut."
  416.  
  417. © 14.09.1991    by Andreas Neumann für AmigaGadget von Nils Kassube
  418.                                    und Purity von Steppenbrand und Diesel
  419.  
  420.  
  421.